﻿#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

// 日期时间类 - 简化实现
class DateTime {
private:
    string date;  // YYYY-MM-DD
    string time;  // HH:MM

public:
    DateTime(string d = "", string t = "") : date(d), time(t) {}

    string toString() const {
        return date + " " + time;
    }

    friend istream& operator>>(istream& is, DateTime& dt) {
        cout << "日期 (YYYY-MM-DD): ";
        is >> dt.date;
        cout << "时间 (HH:MM): ";
        is >> dt.time;
        return is;
    }
};

// 乘客类
class Passenger {
private:
    string name;
    string idNumber;

public:
    void inputInfo() {
        cout << "请输入姓名: ";
        cin >> name;
        cout << "请输入身份证号: ";
        cin >> idNumber;
    }

    void saveToFile(ofstream& file) const {
        file << name << "," << idNumber << endl;
    }
};

// 火车类
class Train {
private:
    string trainNumber;
    string departureStation;
    string destination;
    DateTime departureTime;
    DateTime arrivalTime;
    double price;
    int availableSeats;

public:
    Train(string num = "", string dep = "", string dest = "",
        DateTime depTime = DateTime(), DateTime arrTime = DateTime(),
        double pr = 0, int seats = 0)
        : trainNumber(num), departureStation(dep), destination(dest),
        departureTime(depTime), arrivalTime(arrTime),
        price(pr), availableSeats(seats) {}

    // Getters
    string getTrainNumber() const { return trainNumber; }
    string getDestination() const { return destination; }
    int getAvailableSeats() const { return availableSeats; }

    // 订票
    bool bookTicket() {
        if (availableSeats > 0) {
            availableSeats--;
            return true;
        }
        return false;
    }

    // 修改信息
    void modifyInfo() {
        cout << "请输入新的信息（留空则保持不变）：" << endl;

        string temp;
        cout << "车次 [" << trainNumber << "]: ";
        cin >> temp;
        if (!temp.empty()) trainNumber = temp;

        cout << "始发站 [" << departureStation << "]: ";
        cin >> temp;
        if (!temp.empty()) departureStation = temp;

        cout << "终点站 [" << destination << "]: ";
        cin >> temp;
        if (!temp.empty()) destination = temp;

        cout << "出发时间:" << endl;
        cin >> departureTime;

        cout << "到达时间:" << endl;
        cin >> arrivalTime;

        cout << "票价 [" << price << "]: ";
        cin >> temp;
        if (!temp.empty()) price = stod(temp);

        cout << "剩余座位 [" << availableSeats << "]: ";
        cin >> temp;
        if (!temp.empty()) availableSeats = stoi(temp);

        cout << "火车信息已更新！" << endl;
    }

    // 显示信息
    void displayInfo() const {
        cout << "车次: " << trainNumber << endl;
        cout << "始发站: " << departureStation << endl;
        cout << "终点站: " << destination << endl;
        cout << "出发时间: " << departureTime.toString() << endl;
        cout << "到达时间: " << arrivalTime.toString() << endl;
        cout << "票价: " << price << "元" << endl;
        cout << "剩余座位: " << availableSeats << endl;
        cout << "----------------------------" << endl;
    }

    // 保存到文件
    void saveToFile(ofstream& file) const {
        file << trainNumber << ","
            << departureStation << ","
            << destination << ","
            << departureTime.toString() << ","
            << arrivalTime.toString() << ","
            << price << ","
            << availableSeats << endl;
    }

    // 从文件加载
    void loadFromFile(string line) {
        size_t pos1 = line.find(',');
        size_t pos2 = line.find(',', pos1 + 1);
        size_t pos3 = line.find(',', pos2 + 1);
        size_t pos4 = line.find(',', pos3 + 1);
        size_t pos5 = line.find(',', pos4 + 1);
        size_t pos6 = line.find(',', pos5 + 1);

        trainNumber = line.substr(0, pos1);
        departureStation = line.substr(pos1 + 1, pos2 - pos1 - 1);
        destination = line.substr(pos2 + 1, pos3 - pos2 - 1);

        // 解析日期时间
        string depTimeStr = line.substr(pos3 + 1, pos4 - pos3 - 1);
        string arrTimeStr = line.substr(pos4 + 1, pos5 - pos5 - 1);

        size_t space1 = depTimeStr.find(' ');
        size_t space2 = arrTimeStr.find(' ');

        string depDate = depTimeStr.substr(0, space1);
        string depTime = depTimeStr.substr(space1 + 1);
        string arrDate = arrTimeStr.substr(0, space2);
        string arrTime = arrTimeStr.substr(space2 + 1);

        departureTime = DateTime(depDate, depTime);
        arrivalTime = DateTime(arrDate, arrTime);

        price = stod(line.substr(pos5 + 1, pos6 - pos5 - 1));
        availableSeats = stoi(line.substr(pos6 + 1));
    }
};

// 车票类
class Ticket {
private:
    Train train;
    Passenger passenger;
    string ticketNumber;
    bool isValid;

public:
    Ticket(const Train& t, const Passenger& p)
        : train(t), passenger(p), isValid(true) {
        // 生成简单的票号
        static int counter = 1000;
        ticketNumber = "T" + train.getTrainNumber() + "-" + to_string(counter++);
    }

    void displayInfo() const {
        cout << "车票编号: " << ticketNumber << endl;
        cout << "状态: " << (isValid ? "有效" : "已退票") << endl;
        train.displayInfo();
    }

    void saveToFile(ofstream& file) const {
        file << ticketNumber << "," << (isValid ? "1" : "0") << endl;
        train.saveToFile(file);
        // 保存乘客信息
        ofstream passengerFile("passengers.dat", ios::app);
        if (passengerFile.is_open()) {
            passenger.saveToFile(passengerFile);
            passengerFile.close();
        }
    }
};

// 火车票订票系统类
class TrainBookingSystem {
private:
    vector<Train> trains;
    vector<Ticket> tickets;
    string trainsFileName = "trains.dat";
    string ticketsFileName = "tickets.dat";

public:
    // 构造函数：加载数据
    TrainBookingSystem() {
        loadTrains();
        loadTickets();
    }

    // 析构函数：保存数据
    ~TrainBookingSystem() {
        saveTrains();
        saveTickets();
    }

    // 1. 添加模块
    void addTrain() {
        Train newTrain;

        cout << "请输入车次: ";
        string trainNumber;
        cin >> trainNumber;

        // 检查车次是否已存在
        for (const auto& train : trains) {
            if (train.getTrainNumber() == trainNumber) {
                cout << "错误：该车次已存在！" << endl;
                return;
            }
        }

        newTrain = Train(trainNumber);

        cout << "请输入始发站: ";
        string departureStation;
        cin >> departureStation;
        newTrain = Train(trainNumber, departureStation);

        cout << "请输入终点站: ";
        string destination;
        cin >> destination;

        cout << "出发时间:" << endl;
        DateTime departureTime;
        cin >> departureTime;

        cout << "到达时间:" << endl;
        DateTime arrivalTime;
        cin >> arrivalTime;

        cout << "请输入票价: ";
        double price;
        cin >> price;

        cout << "请输入总座位数: ";
        int totalSeats;
        cin >> totalSeats;

        newTrain = Train(trainNumber, departureStation, destination,
            departureTime, arrivalTime, price, totalSeats);

        trains.push_back(newTrain);
        cout << "火车信息添加成功！" << endl;
    }

    // 2. 查询模块
    void searchTrain() {
        int choice;
        cout << "请选择查询方式：" << endl;
        cout << "1. 按车次查询" << endl;
        cout << "2. 按目的地查询" << endl;
        cin >> choice;

        if (choice == 1) {
            string trainNumber;
            cout << "请输入车次: ";
            cin >> trainNumber;

            bool found = false;
            for (const auto& train : trains) {
                if (train.getTrainNumber() == trainNumber) {
                    train.displayInfo();
                    found = true;
                    break;
                }
            }

            if (!found) {
                cout << "未找到该车次！" << endl;
            }
        }
        else if (choice == 2) {
            string destination;
            cout << "请输入目的地: ";
            cin >> destination;

            bool found = false;
            for (const auto& train : trains) {
                if (train.getDestination() == destination) {
                    train.displayInfo();
                    found = true;
                }
            }

            if (!found) {
                cout << "未找到前往该目的地的车次！" << endl;
            }
        }
        else {
            cout << "无效的选择！" << endl;
        }
    }

    // 3. 订票模块
    void bookTicket() {
        string destination;
        cout << "请输入目的地: ";
        cin >> destination;

        // 查找可用车次
        vector<Train> availableTrains;
        for (const auto& train : trains) {
            if (train.getDestination() == destination && train.getAvailableSeats() > 0) {
                availableTrains.push_back(train);
            }
        }

        if (availableTrains.empty()) {
            cout << "没有前往该目的地的可用车次！" << endl;
            return;
        }

        // 显示可用车次
        cout << "可用车次列表：" << endl;
        for (size_t i = 0; i < availableTrains.size(); i++) {
            cout << "[" << i + 1 << "]" << endl;
            availableTrains[i].displayInfo();
        }

        // 用户选择车次
        int choice;
        cout << "请选择要预订的车次 (1-" << availableTrains.size() << "): ";
        cin >> choice;

        if (choice < 1 || choice > availableTrains.size()) {
            cout << "无效的选择！" << endl;
            return;
        }

        Train selectedTrain = availableTrains[choice - 1];

        // 输入乘客信息
        Passenger passenger;
        passenger.inputInfo();

        // 确认订票
        char confirm;
        cout << "确认预订此车票吗？(Y/N): ";
        cin >> confirm;

        if (confirm == 'Y' || confirm == 'y') {
            // 更新火车座位信息
            for (auto& train : trains) {
                if (train.getTrainNumber() == selectedTrain.getTrainNumber()) {
                    if (train.bookTicket()) {
                        // 创建车票
                        Ticket newTicket(train, passenger);
                        tickets.push_back(newTicket);

                        cout << "订票成功！" << endl;
                        newTicket.displayInfo();
                        break;
                    }
                    else {
                        cout << "订票失败：该车次已无余票！" << endl;
                    }
                    return;
                }
            }
        }
        else {
            cout << "订票已取消！" << endl;
        }
    }

    // 4. 修改模块
    void modifyTrain() {
        string trainNumber;
        cout << "请输入要修改的车次: ";
        cin >> trainNumber;

        bool found = false;
        for (auto& train : trains) {
            if (train.getTrainNumber() == trainNumber) {
                train.modifyInfo();
                found = true;
                break;
            }
        }

        if (!found) {
            cout << "未找到该车次！" << endl;
        }
    }

    // 5. 显示模块
    void showTrains() {
        if (trains.empty()) {
            cout << "暂无火车信息！" << endl;
            return;
        }

        cout << "所有火车信息：" << endl;
        for (const auto& train : trains) {
            train.displayInfo();
        }
    }

    void showTickets() {
        if (tickets.empty()) {
            cout << "暂无车票信息！" << endl;
            return;
        }

        cout << "所有车票信息：" << endl;
        for (const auto& ticket : tickets) {
            ticket.displayInfo();
            cout << "----------------------------" << endl;
        }
    }

    // 6. 保存模块
    void saveTrains() {
        ofstream file(trainsFileName);
        if (file.is_open()) {
            for (const auto& train : trains) {
                train.saveToFile(file);
            }
            file.close();
        }
        else {
            cout << "无法打开文件 " << trainsFileName << " 进行保存！" << endl;
        }
    }

    void saveTickets() {
        ofstream file(ticketsFileName);
        if (file.is_open()) {
            for (const auto& ticket : tickets) {
                ticket.saveToFile(file);
            }
            file.close();
        }
        else {
            cout << "无法打开文件 " << ticketsFileName << " 进行保存！" << endl;
        }
    }

    // 加载数据
    void loadTrains() {
        ifstream file(trainsFileName);
        if (file.is_open()) {
            trains.clear();
            string line;
            while (getline(file, line)) {
                if (!line.empty()) {
                    Train train;
                    train.loadFromFile(line);
                    trains.push_back(train);
                }
            }
            file.close();
        }
    }

    void loadTickets() {
        ifstream file(ticketsFileName);
        if (file.is_open()) {
            tickets.clear();
            // 简化实现，实际需要更复杂的解析逻辑
            file.close();
        }
    }

    // 显示主菜单
    void showMenu() {
        int choice;
        do {
            cout << "\n===== 火车票订票系统 =====" << endl;
            cout << "1. 添加火车信息" << endl;
            cout << "2. 查询火车信息" << endl;
            cout << "3. 订票" << endl;
            cout << "4. 修改火车信息" << endl;
            cout << "5. 显示所有火车信息" << endl;
            cout << "6. 显示所有车票信息" << endl;
            cout << "0. 退出系统" << endl;
            cout << "请输入您的选择: ";
            cin >> choice;

            switch (choice) {
            case 1:
                addTrain();
                break;
            case 2:
                searchTrain();
                break;
            case 3:
                bookTicket();
                break;
            case 4:
                modifyTrain();
                break;
            case 5:
                showTrains();
                break;
            case 6:
                showTickets();
                break;
            case 0:
                cout << "感谢使用火车票订票系统，再见！" << endl;
                break;
            default:
                cout << "无效的选择，请重新输入！" << endl;
            }
        } while (choice != 0);
    }
};

// 主函数
int main() {
    TrainBookingSystem system;
    system.showMenu();
    return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
